/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once
#include <基本类型.h>
#include <set>
#include <filesystem>

#include <字符串转换.h>
#include "core/shader_color.h"
#include "core/shader_std.h"
#include "core/shader_ray.h"
#include "core/GPU.h"

enum class E_VK列队类型 : uint32 {
	e_缺损图形 = 0x0,
	e_计算 = 0x1,
	e_缓存 = 0x2,
};

enum E_绘图API {
	E_Vulkan,
	//E_OpenGL,
	E_DirectX12,
	E_CUDA,
};

//enum class E_管线槽 : uint8 {
//	e_颜色合成,
//	e_阴影,
//	e_环境,
//};
typedef enum : uint64 {
	e_颜色渲染	= 1,
	e_阴影渲染	= 2,
	e_环境渲染	= 4,
	e_几何渲染	= 8,
	e_UI渲染	= 16,
	e_UI合成	= 32,
} E_管线槽;


typedef enum {
	e_shape球体,
	e_shape圆柱,
	e_shape方体,
}E_形状;


typedef enum {
	e_分割方式_切耳,
	e_分割方式_扫描,
}E_三角形分割方式;


enum E_数据格式 {
	e_F_RGBA,
	e_F_R32G32B32A32,
	e_F_RGB,
	e_F_R32G32,
	e_F_R32,

	e_I_R32G32B32A32,
	e_I_R32G32B32,
	e_I_R32G32,
	e_I_R32,

	e_UI_R32G32B32A32,
	e_UI_R32G32B32,
	e_UI_R32G32,
	e_UI_R32,

	e_UI8_RGBA,
	e_UI8_RGB,
	e_UI8_RG,
	e_UI8_R,
};


typedef enum : uint64 {
	e_None				= 1 << 0,
	e_VBO				= 1 << 1,
	e_UBO				= 1 << 2,
	e_TBOs				= 1 << 3,
	e_TBOd				= 1 << 4,
	e_SSBO				= 1 << 5,
	e_SSBOd				= 1 << 6,
	e_INDEX				= 1 << 7,
	e_INDIRECT			= 1 << 8,
	e_AIOMIC			= 1 << 9,
	e_DI				= 1 << 10,


	e_光追BVH			= 1 << 14,
	e_光追实例			= 1 << 15,
	e_光追底层加速结构	= 1 << 16,
	e_光追顶层加速结构	= 1 << 17,
	e_着色列表			= 1 << 18,
	e_着色端内存地址	= 1 << 19,

	e_SAMPLER			= 1 << 12,
	e_SAMPLER_Array		= 1 << 20,

	e_IMAGE_SAMPLER		= 1 << 13,
	e_IMAGE				= 1 << 11,
	e_IMAGE_Array		= 1 << 21,

	e_纹理储存_Array	= 1 << 22,

	e_拷贝目标			= 1 << 30,
	e_图像缓存			= 1 << 31,
	//e_全局缓存			= 1 << 32,
}E_板载缓存类型;




typedef enum : uint32 {
	e_顶点着色		= 1 << 0,
	e_细分控制着色	= 1 << 1,
	e_细分着色		= 1 << 2,
	e_几何着色		= 1 << 3,
	e_像素着色		= 1 << 4,
	e_计算着色		= 1 << 5,
	e_光追射线生成	= 1 << 6,
	//e_命中		,
	e_最近相交		= 1 << 7,
	e_光追忽略相交	= 1 << 8,
	e_光追相交		= 1 << 9,
	e_光追最近相交	= 1 << 10,
	e_光追所有相交  = 1 << 11,
	e_光追AABB		= 1 << 12,
	e_光追回调   	= 1 << 13,
}E_着色阶段;


/*typedef enum : uint8 {
	e_光追阶段_光线生成,
	e_光追阶段_光线忽略,
	e_光追阶段_最近相交,
	e_光追阶段_材质回调,
}E_光追阶段ID;*/
typedef enum : uint32 {
	e_几何着色_面 = 0,
	e_几何着色_边 = 1,
	e_几何着色_线 = 2,
}E_几何着色类型;

typedef enum {
	e_线_连续,
	e_线_闭合,
	e_线_线段,
}E_线绘制模式;


typedef enum : uint32 {
	e_光追阶段ID_光线生成	= 0,
	e_光追阶段ID_光线忽略	= 1,
	//e_光追阶段ID_AABB		= 2,
	e_光追阶段ID_最近相交	= 2,
	
	e_光追阶段ID_材质回调	= 3,
}E_光追阶段ID;

typedef enum : uint32 {
	e_线段 = 0,
	e_连续线 = 1,
	e_曲线线段 = 2,
	e_连续曲线 = 3,
}E_线类型;

typedef enum {
	e_画点集,
	e_画线段,
	e_画连续线,
	e_三角形,
	e_三角形带,
	e_画扇形,

	e_画邻接线段,
	e_画邻接连续线段,

	e_画邻接三角形,
	e_画邻接三角形带,
	e_画曲线,
}E_绘制方式;


typedef enum : uint32 {
	e_填充点,
	e_填充线,
	e_填充面,
	e_填边面,
	e_填曲线,
	e_填曲线控制点,
	e_填曲线控制线,
	e_填充纵向刻度线,
}E_填充模式;

enum E_混合模式 : uint32 {
	e_相加,
	e_相减,
	e_反向相减,
	e_最小,
	e_最大,
	e_相乘,
	e_零,
	e_源,
	e_目标,
	e_反向,
};

enum E_混合因子 {
	e_混合因子零,
	e_混合因子一,
	e_源颜色,
	e_一减源颜色,
	e_目标颜色,
	e_一减目标颜色,
	e_源透明通道,
	e_一减源透明通道,
	e_目标透明通道,
	e_一减目标透明通道,
};

enum E_图层混合模式 : uint32 {
	//正常
	e_Normal = DEF_Blend_Normal,
	e_Screen = DEF_Blend_Screen,
	e_Multiply = DEF_Blend_Multiply,

	e_Dissolve = DEF_Blend_Dissolve,
	e_Darken = DEF_Blend_Darken,
	e_ColorBurn = DEF_Blend_ColorBurn,
	e_LinearBurn = DEF_Blend_LinearBurn,
	e_Lighten = DEF_Blend_Lighten,
	
	e_SoftLight = DEF_Blend_SoftLight,

	e_Line_Normal,
};


//============================================== 纹理 ===================================================
enum E_纹理类型 : uint32 {
	//正常
	e_Tex1D			= DEF_Texture_Type_1D,
	e_Tex1DArray	= DEF_Texture_Type_1DArray,
	e_Tex2D			= DEF_Texture_Type_2D,
	e_Tex3D			= DEF_Texture_Type_2DArray,
	e_Tex2DArray	= DEF_Texture_Type_3D,
	e_Tex3DArray	= DEF_Texture_Type_3DArray,
	e_TexCube		= DEF_Texture_Type_Cube,
	e_TexCubeArray	= DEF_Texture_Type_CubeArray,
};

enum E_纹理拉伸方式 : uint32 {
	e_重复,
	e_镜像重复,
	e_边缘,
	e_镜像边缘,
	e_边框,
};



typedef enum : uint32 {
	e_光追渲染_关,
	e_光追渲染_单帧,
	e_光追渲染_序列,

	e_离线计算_单帧,
	e_离线计算_序列,
}E_离线渲染状态;




enum E_网格数据枚举 {
	e_Mesh_CPU,
	e_Mesh_CUDA,
	e_Mesh_Vulkan
};

enum E_投影模式 {
	e_透视,
	e_正交,
};

typedef enum {
	E_粒子物体_点,
	E_粒子物体_网格,
	E_粒子物体_网格集合,
	E_粒子物体_物理后端映射,
}E_粒子绘制类型;

enum E_RenderLayerType {
	e_renderLayer_composite = DEF_renderLayer_composite,
	e_renderLayer_diffuse = DEF_renderLayer_albedo,
	e_renderLayer_depth = DEF_renderLayer_depth,
	e_renderLayer_normal = DEF_renderLayer_normal,
	e_renderLayer_illuminate = DEF_renderLayer_illuminate,
	e_renderLayer_shadow = DEF_renderLayer_shadow,

	e_renderLayer_end,
};



typedef enum {
	e_绘图设备,
	e_计算设备,
}E_设备类型;





typedef enum : uint8 {
	e_填充布局,
	e_HBOX布局,
	e_VBOX布局,
	e_BOX布局,
	e_网格,
	e_等比,
}E_布局方式;

typedef enum : uint8 {
	e_左对齐,
	e_右对齐,
	e_据中对齐,
	e_纵向齐,
}E_对齐方式;




enum class E_键位执行状态 : uint8 {
	e_准备,
	e_开始,
	e_执行,
	e_完成,
};

typedef enum : uint8 {
	e_拖放_开始,
	e_拖放_进行,
	e_拖放_结束,
}E_拖放状态;

typedef enum : uint8 {
	e_键位_任意,
	e_键位_按下,
	e_键位_放开,
	e_键位_单击,
	e_键位_双击,
	e_键位_拖放,

	e_键位_拖放开始,
	e_键位_拖放进行,
	e_键位_拖放结束,
}E_键位操作类型;








typedef enum {
	e_smaple_线性,
	e_smaple_波形,
	e_smaple_噪波,
}E_采样条类型;

typedef enum {
	e_移动方式_自由,
	e_移动方式_固定,
}E_移动方式;

/*typedef struct {
	vec3			m_深度偏移;


	S_结构对象指针	m_视图投影矩阵;
	//S_结构对象指针	m_矩阵;
	S_结构对象指针	m_视口;
	S_结构对象指针	m_裁剪;
	S_结构对象指针	m_GPU参数;



	S_板载缓存* m_间接绘制参数;

	//S_结构对象指针	m_顶点属性;
	//S_结构对象指针	m_片源属性;
	float32			m_线宽;
	

	uint32			m_实例数量;
	uint32			m_间接数量;

}S_渲染参数;*/




typedef struct {
	class S_板载缓存* m_索引;
	uint32		m_实例数量;
}S_索引渲染参数;

typedef struct {
	vec2		m_方向;

	vec4* m_颜色;
	float32* m_颜色点;

	uint32		m_颜色点数量;
}S_2D渐变;

typedef struct {
	S_结构指针 m_Surface3D;
	S_结构指针 m_Scene;
}S_帧渲染层;




//============================================== 网格数据 ==========================================================

typedef enum : uint64 {
	e_网格预设_未知 = DEF_字符串拼接ID('n', 'o', 'n', 'e', '\0', '\0', '\0', '\0'),
	e_网格预设_球体 = DEF_字符串拼接ID('Q', 'T', '\0', '\0', '\0', '\0', '\0', '\0'),
	e_网格预设_圆柱 = DEF_字符串拼接ID('Y', 'Z', '\0', '\0', '\0', '\0', '\0', '\0'),
	e_网格预设_X轴箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'x', '\0', '\0', '\0'),
	e_网格预设_Y轴箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'y', '\0', '\0', '\0'),
	e_网格预设_Z轴箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'z', '\0', '\0', '\0'),
	e_网格预设_十字叉 = DEF_字符串拼接ID('S', 'Z', 'X', '\0', '\0', '\0', '\0', '\0'),

	e_网格预设_X轴旋转箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'x', 'r', '\0', '\0'),
	e_网格预设_Y轴旋转箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'y', 'r', '\0', '\0'),
	e_网格预设_Z轴旋转箭头 = DEF_字符串拼接ID('Z', 'X', 'J', 'T', 'z', 'r', '\0', '\0'),

}E_网格预设类型;


typedef enum : uint32 {
	e_MT_面 = 0,
	e_MT_边 = 1,
	e_MT_点 = 2,
	e_MT_框 = 3,
	
	e_MT_焦点 = 4,

	e_MT_光照 = 5,
	e_MT_纹理 = 6,
	e_MT_轮廓边 = 7,
	e_MT_线 = 8,

	

	e_MT_预览 = 9,
	e_MT_渲染 = 10,
}E_物体网格元素类型;

typedef enum {
	
	e_OVS_边框	= 1 << E_物体网格元素类型::e_MT_框,
	e_OVS_面	= 1 << E_物体网格元素类型::e_MT_面,
	e_OVS_边	= 1 << E_物体网格元素类型::e_MT_边,
	e_OVS_轮廓	= 1 << E_物体网格元素类型::e_MT_焦点,
	e_OVS_点	= 1 << E_物体网格元素类型::e_MT_点,

	e_OVS_光照 = 1 << E_物体网格元素类型::e_MT_光照,
	e_OVS_纹理 = 1 << E_物体网格元素类型::e_MT_纹理,
	
	e_OVS_预览 = 1 << E_物体网格元素类型::e_MT_预览,
	e_OVS_渲染 = 1 << E_物体网格元素类型::e_MT_渲染,

}E_物体视口显示;

typedef enum : uint64 {
	//e_渲染模式_白模 = DEF_字符串拼接ID('B', 'M', '\0', '\0', '\0', '\0', '\0', '\0'),
	//e_渲染模式_纹理 = DEF_字符串拼接ID('W', 'L', '\0', '\0', '\0', '\0', '\0', '\0'),
	//e_渲染模式_光栅 = DEF_字符串拼接ID('G', 'S', '\0', '\0', '\0', '\0', '\0', '\0'),
	//e_渲染模式_光追 = DEF_字符串拼接ID('G', 'Z', '\0', '\0', '\0', '\0', '\0', '\0'),

	e_渲染模式_白模 = 0,
	e_渲染模式_纹理 = 1,
	e_渲染模式_光栅 = 2,
	e_渲染模式_光追 = 3,
	e_渲染模式_外部 = 4,
}E_物体渲染模式;

typedef enum : int32 {
	e_渲染调试_合成 = 0,
	e_渲染调试_颜色 = 1,
	e_渲染调试_深度 = 2,
	e_渲染调试_法线 = 3,
}E_视口渲染调试层;

enum E_基本材质类型 {
	e_单色材质,
};






typedef enum {
	e_In鼠标,
	e_In键盘,
	e_In游戏杆,
	e_In鼠标扩展1,
	e_In鼠标扩展2,
	e_In键盘扩展1,
	e_In键盘扩展2,
}E_输入设备类型预设;

typedef enum {
	e_鼠标左键,
	e_鼠标右键,
	e_鼠标中键,

	e_鼠标键Ex0,
	e_鼠标键Ex1,
	e_鼠标键Ex2,
	e_鼠标键Ex3,
	e_鼠标键Ex4,
	e_鼠标键Ex5,
	e_鼠标键Ex6,
}E_鼠标按钮;



typedef enum {
	e_KCapsLk = 0,
	e_KShift = 1,
	e_KNum = 2,
}E_控制键;


typedef struct {
	int32    lX;
	int32    lY;
	int32    lZ;
	uint8    rgbButtons[4];
	//uint8	按钮姿态[8];
}S_鼠标属性;


typedef struct {
	vec2		gPos;
	vec2		lPos;
	//精准步进
	vec2		abs;
	vec2		相对窗口偏移;
	float32		lZ;
	uint8		rgbButtons[4];
}S_鼠标;


typedef struct {
	uint8*	Keys;
	uint8*	Keys状态;
	uint8	lockKey[4];
}S_键盘;



typedef enum {
	e_本体,
	e_引用,
}E_属性引用类型;



typedef enum {
	e_mt_点 = 0,
	e_mt_面 = 1,
	e_mt_线段 = 2,
	e_mt_连续线 = 3,
}E_网格类型;


/****************************************** 多边形 *****************************************/






//====================================== 物体 =========================================

typedef enum : uint64 {
	t_空,

	t_网格物体 = DEF_ObType_Mesh,
	t_灯光 = DEF_ObType_Ligth,
	t_平行光 = DEF_ObType_Ligth_Parallel,
	t_点光源 = DEF_ObType_Ligth_Point,
	t_区域光 = DEF_ObType_Ligth_Area,
	t_聚光灯 = DEF_ObType_Ligth_Spot,

	t_区域光_方形 = DEF_ObType_Ligth_RectArea,
	t_区域光_圆形 = DEF_ObType_Ligth_CircleArea,

	t_实例,
	t_线,
	t_线段,
	t_粒子,

	t_多边形,
	t_摄像机,
	t_骨骼,
	t_骨架,


	t_物体包,
	t_包,
	t_虚拟体,
	t_标注,
	t_微多边形,

	t_可编辑骨骼,
	t_骨节,

	t_物理几何虚拟体 = DEF_字符串拼接ID('P', 'h', 'y', 'G', 'e', 'o', 'm', '\0'),
	t_物理体 = DEF_字符串拼接ID('P', 'h', 'y', 'B', 'o', 'd', 'y', '\0'),
	t_物理力 = DEF_字符串拼接ID('p', 'h', 'y', 'f', '\0', '\0', '\0', '\0'),
	t_点 = DEF_字符串拼接ID('P', 'o', 'i', 'n', 't', '\0', '\0', '\0'),
	t_实例物体 = DEF_字符串拼接ID('I', 'n', 's', 't', 'O', 'B', '\0', '\0'),
	t_包围盒 = DEF_字符串拼接ID('B', 'o', 'u', 'n', 'd', '\0', '\0', '\0'),
	t_空间曲线 = DEF_字符串拼接ID('c', 'u', 'r', 'v', 'e', '3', 'd', '\0'),
	t_场景 = DEF_字符串拼接ID('s', 'c', 'e', 'n', 'e', '\0', '\0', '\0'),
	t_集合 = DEF_字符串拼接ID('J', 'H', '\0', '\0', '\0', '\0', '\0', '\0'),

	t_网格缓存 = DEF_字符串拼接ID('m', 'e', 's', 'h', '\0', '\0', '\0', '\0'),
	t_粒子系统 = DEF_字符串拼接ID('L', 'Z', 'X', 'T', '\0', '\0', '\0', '\0'),

	t_渲染世界 = DEF_字符串拼接ID('X', 'R', 'S', 'J', '\0', '\0', '\0', '\0'),
	t_渲染层 = DEF_字符串拼接ID('X', 'R', 'C', '\0', '\0', '\0', '\0', '\0'),
	t_渲染物体 = DEF_字符串拼接ID('X', 'R', 'W', 'T', '\0', '\0', '\0', '\0'),

	t_物体节点 = DEF_字符串拼接ID('o', 'b', 'n', 'o', 'd', 'e', '\0', '\0'),
	t_场景节点 = DEF_字符串拼接ID('s', 'c', 'n', 'o', 'd', 'e', '\0', '\0'),

	t_GL立即模式,
}E_物体类型;




//======================================= 物理 ===========================================

enum E_施加力类型 {
	e_重力 = 0,
	e_直线,
	e_扭矩,
	e_关节,
	e_控制,
	施加力类型_MAX_NUM_TIRE_TYPES
};

enum E_物理体链接类型 {
	e_自由,
	e_铰链,
	e_滑动,
	e_球型,
	e_固定,

	e_旋转滑动,
	e_圆柱活塞,
	e_约束球,

	链接类型_MAX_NUM_TIRE_TYPES
};

typedef enum {
	E_物理体_空,
	
	E_物理体_流体 = DEF_ParticleType_fluid,
	E_物理体_流入 = DEF_ParticleType_inflow,

	E_物理体_刚体 = DEF_ParticleType_rigidBody,
	
	E_物理体_柔体 = DEF_ParticleType_flexibleBody,
	E_物理体_布料 = DEF_ParticleType_cloth,
	
	E_物理体_流出 = DEF_ParticleType_outflow,

	
	E_物理体_控制 = DEF_ParticleType_control,
	E_物理体_静态 = DEF_ParticleType_static,
	E_物理体_车辆 = DEF_ParticleType_vehicle,
	
	
	
	//E_物理体_流体填充,
}E_物理体类型;


enum E_物理几何体类型 {
	E_碰撞几何_方体,
	E_碰撞几何_圆柱,
	E_碰撞几何_球体,
	E_碰撞几何_胶囊,
	E_碰撞几何_凸壳,
	E_碰撞几何_平面,
	
	E_碰撞几何_网格,
	E_碰撞几何_地形,
};

typedef enum {
	E_物理引擎_Mujoco,		//0
	E_物理引擎_MPM,			//5
	E_物理引擎_Bullet,		//1
	E_物理引擎_PBF,			//2
	
	E_物理引擎_PhysX,		//4
	
	E_物理引擎_FLIP,		//6
	
	//E_物理引擎_ODE,			//6
	//E_物理引擎_NewTon,		//7
	
	//E_物理引擎_Chrono,		//8
	E_物理引擎_None,
}E_物理引擎;





typedef struct {
	S_结构指针	m_Buf;
	E_板载缓存类型	m_Type;
}S_2D绘制GPU参数元素;


typedef enum {
	e_pu_位置 = 1 << 0,
	e_pu_速度 = 1 << 1,
	e_pu_旋转 = 1 << 2,
	e_pu_大小 = 1 << 3,
	e_pu_寿命 = 1 << 4,
	e_pu_年龄 = 1 << 5,
}E_粒子更新属性;




//============================================= UI ===================================================

typedef enum : uint8 {
	e_鼠标样式_默认,
	e_鼠标样式_横向双箭头,
	e_鼠标样式_纵向双箭头,
	e_鼠标样式_等待,
}E_鼠标样式;

typedef enum : uint8 {
	e_读取,
	e_写入,
	e_关闭,
	e_打开路径,
}E_对话框类型;

typedef enum : uint8 {
	e_列表模式_垂直,
	e_列表模式_水平,
	e_列表模式_缩略,
}E_列表显示模式;

enum E_UI绘制调整部分 {
	e_位置 = 1 << 0,
	e_大小 = 1 << 1,
	e_进入 = 1 << 2,
	e_退出 = 1 << 2,
	e_All = 0xffffffff,
};

typedef enum : uint64 {
	t_窗口 = DEF_字符串拼接ID('w', 'i', 'n', 'd', 'o', 'w', 'n', '\0'),
	

	t_菜单 = DEF_字符串拼接ID('m', 'e', 'n', 'u', '\0', '\0', '\0', '\0'),
	t_枚举表 = DEF_字符串拼接ID('m', 'n', 'u', 'm', '\0', '\0', '\0', '\0'),
	t_多选框 = DEF_字符串拼接ID('m', 's', 'b', '\0', '\0', '\0', '\0', '\0'),
	t_分割框 = DEF_字符串拼接ID('s', 'p', 'l', 'i', 't', 'b', 'o', 'x'),
	t_菜单项 = DEF_字符串拼接ID('m', 'e', 'n', 'u', 'i', 't', 'e', 'm'),
	t_时间视口 = DEF_字符串拼接ID('t', 'i', 'm', 'e', 'l', 'l', 'n', 'e'),
	t_轨道视口 = DEF_字符串拼接ID('t', 'r', 'a', 'c', 'k', '\0', '\0', '\0'),
	t_分割手柄 = DEF_字符串拼接ID('s', 'p', 'l', 't', 'h', 'n', 'd', 'l'),
	t_弹出消息框 = DEF_字符串拼接ID('i', 'n', 'f', 'o', 'b', 'o', 'x', '\0'),
	t_文本编辑框 = DEF_字符串拼接ID('t', 'e', 'x', 't', 'e', 'd', 'i', 't'),
	t_行文本编辑框 = DEF_字符串拼接ID('l', 'i', 'n', 'e', 'e', 'd', 'i', 't'),

	t_文件对话框 = DEF_字符串拼接ID('d', 'i', 'a', 'l', 'o', 'g', 'f', '\0'),

	t_标量 = DEF_字符串拼接ID('v', 'e', 'l', '\0', '\0', '\0', '\0', '\0'),
	t_矢量 = DEF_字符串拼接ID('v', 'e', 'c', '\0', '\0', '\0', '\0', '\0'),
	
}E_WidgetType;


typedef enum : uint32 {
	e_鼠标拖放_文本选择,
	e_鼠标拖放_组件移动,
	e_鼠标拖放_分割条,
	e_鼠标拖放_滚动条,
	e_鼠标拖放_静态移动,
	e_鼠标拖放_默认类型结束,
}E_拖放数据类型;

typedef enum {
	e_拖放_NUL = E_拖放数据类型::e_鼠标拖放_默认类型结束,
	e_拖放_插座,
	e_拖放_节点,
	e_拖放_时间线,
	e_节点面板移动,
	e_节点视口框选,
	e_拖放_节点子集按钮,
	e_拖放_库节点模块项加载,
	e_拖放_库节点模块项保存,
	e_拖放_库_插件加载,
}E_自定义拖放数据类型;

enum E_窗口类型 {
	E_Win32,
	E_SDL,
	E_Glfw,
};

enum class E_菜单关闭方式 {
	e_鼠标离开,
	e_回车输入,
	e_ESC取消,
};



/*inline S_Operator f_alloc_Ops(fp_Operator func, S_结构对象指针 obj) {
	S_Operator ops;
	ops.m_Func = func;
	ops.m_Obj = obj;
	return ops;
}*/



typedef struct {
	S_结构指针	m_Obj;
	int8			m_Min;
	int8			m_Max;
}S_PropValue8;

typedef struct {
	S_结构指针	m_Obj;
	uint8			m_Min;
	uint8			m_Max;
}S_PropValue8u;

typedef struct {
	S_结构指针	m_Obj;
	int16			m_Min;
	int16			m_Max;
}S_PropValue16;

typedef struct {
	S_结构指针	m_Obj;
	uint16			m_Min;
	uint16			m_Max;
}S_PropValue16u;

typedef struct {
	S_结构指针	m_Obj;
	int32			m_Min;
	int32			m_Max;
}S_PropValue32;

typedef struct {
	S_结构指针	m_Obj;
	uint32			m_Min;
	uint32			m_Max;
}S_PropValue32u;

typedef struct {
	S_结构指针	m_Obj;
	float32			m_Min;
	float32			m_Max;
}S_PropValueF32;

typedef struct {
	std::u16string*	m_ICO;
	std::u16string*	m_Names;
	int32*			m_当前选项;
	uint8			m_展开;
}S_PropValueEnum;

struct S_标题和图标 {
	std::u16string m_标题;
	std::u16string m_图标;
};




typedef enum : uint32 {
	e_事件传递_继续,
	e_事件传递_终止,
}E_事件是否传递;

typedef enum : uint32 {
	e_键映射类型_键盘,
	e_键映射类型_鼠标,
	e_键映射类型_拖放,
	e_键映射类型_双击,
	e_键映射类型_拖拽,
}E_键位映射类型;

enum class E_字符输入类型 : uint32 {
	e_常规,
	
	e_输入法字符,
	e_输入法组合,
	e_末尾行插入,
	e_拆分行,
};




enum E_场景物体容器类型 {
	e_链表,
	e_数组,
	e_映射,
	e_集合
};





#define DEF_alloc_属性数据(obj, type, min, max) 	\
	type* obj = (type*)malloc(sizeof(type));		\
	{												\
		obj->m_Min = min;							\
		obj->m_Max = max;							\
	}												\



struct S_板载缓存;

enum E_属性值映射方式 {
	e_属性值映射_独立创建 = 0,
	e_属性值映射_外部指针 = 1,
};


typedef void(*fp_PropUpdate)(struct S_Props& prop);
typedef struct {
	std::set<struct C_Widget*>* m_LinkWidget;
	struct C_Widget*	m_部件;
	fp_PropUpdate		m_Update;		//外部创建 UI内部调用
	fp_PropUpdate		m_Set;			//UI内部创建 外部调用
	S_结构指针			m_关键帧;
}S_Props_UI;

struct S_UI风格属性 {
	std::u16string	m_ICO;
	S_GPU内存块*	m_图元形状;
};

typedef struct S_Props {
	E_值类型		m_Type;
	S_结构指针		m_Value;
	
	std::u16string	m_Name;
	

	S_Props_UI*		m_UI;
	S_UI风格属性*	m_风格属性;

	S_结构指针		m_关键帧;
	S_GPU内存块		m_GPU缓存[2];
	uint32			m_值元素个数;
	uint8			m_私有;			//只有创建它的地方释放
	uint8			m_值映射类型;
	E_布局方式		m_布局方式;
}S_Props;

#define DEF_alloc_Props_UI_Ptr(prop) {((prop).m_UI) = (S_Props_UI*)malloc(sizeof(S_Props_UI)); *((prop).m_UI) = {nullptr, nullptr, nullptr, nullptr, nullptr};}
//#define DEF_alloc_Props_UI_Ptr(prop) ((prop).m_UI) = {nullptr, nullptr, nullptr};
#define DEF_release_Props_UI_Ptr(prop) free((prop).m_UI)
//#define DEF_release_Props_UI_Ptr(prop) 


Inline S_Props f_prop_init(E_值类型 类型, void* data, const std::u16string& name, E_属性值映射方式 映射) {
	S_Props prop{};

	prop.m_Type = 类型;
	prop.m_Name = name;
	prop.m_Value = (S_结构指针)data;

	prop.m_UI = nullptr;
	//prop.m_部件 = nullptr;

	prop.m_关键帧 = nullptr;
	prop.m_GPU缓存[0] = {};
	prop.m_GPU缓存[1] = {};
	
	prop.m_私有 = false;
	prop.m_布局方式 = E_布局方式::e_HBOX布局;
	prop.m_值映射类型 = 映射;

	switch (类型) {
		case E_值类型::e_Type_uVec2:
		case E_值类型::e_Type_iVec2:
		case E_值类型::e_Type_Vec2: prop.m_值元素个数 = 2; break;
		
		case E_值类型::e_Type_RGB:
		case E_值类型::e_Type_uVec3:
		case E_值类型::e_Type_iVec3:
		case E_值类型::e_Type_Vec3: prop.m_值元素个数 = 3; break;

		case E_值类型::e_Type_uVec4:
		case E_值类型::e_Type_iVec4:
		case E_值类型::e_Type_Vec4:
		case E_值类型::e_Type_RGBA:
		case E_值类型::e_Type_RGBA8: prop.m_值元素个数 = 4; break;

		case E_值类型::e_Type_UI32_FlagBits: prop.m_值元素个数 = 32; break;
		default:
			prop.m_值元素个数 = 1;
			break;
	}
	return prop;
}



//使用 f_alloc_Ops 创建"S_Operator" 对象和名称传入到参数
/*inline S_Props f_alloc_OpsProp(S_Operator* ops, std::wstring name) {
	S_Props prop = { E_值类型::e_Type_Operator, (S_结构对象指针)ops, name, nullptr, 1, false };
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}*/


inline S_Props f_alloc_NoneProp() {
	S_Props prop = { E_值类型::e_Type_None, nullptr, u"", {}, nullptr, {nullptr}, 0, false, 0 };
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

inline S_Props f_alloc_I8Prop(int8* value, std::u16string name, int8 min = -127, int8 max = 127) {
	E_属性值映射方式 值映射类型;
	if (value == nullptr) {
		value = (int8*)malloc(sizeof(int8));
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_I8, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_I8, value, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

inline S_Props f_alloc_UI8Prop(uint8* value, std::u16string name, uint8 min = 0, uint8 max = 255) {
	E_属性值映射方式 值映射类型;
	if (value == nullptr) {
		value = (uint8*)malloc(sizeof(uint8));
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_UI8, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_UI8, value, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

inline S_Props f_alloc_I32Prop(int32* value, std::u16string name, int32 min = 0x0fffffff, int32 max = 0xffffffff) {
	E_属性值映射方式 值映射类型;
	if (value == nullptr) {
		value = (int32*)malloc(sizeof(int32));
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_I32, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_I32, value, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
inline S_Props f_alloc_UI32Prop(uint32* value, std::u16string name, uint32 初始值=0, uint32 min = 0, uint32 max = 0xfffffff) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (uint32*)malloc(sizeof(uint32));
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_UI32, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_UI32, value, name, 映射类型);
	prop.m_值映射类型 = 映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
inline S_Props f_alloc_UI64Prop(uint64* value, std::u16string name, uint64 min = 0, uint64 max = 0xfffffffffffffff) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (uint64*)malloc(sizeof(uint64));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//DEF_alloc_属性数据(obj, S_PropValue32u, min, max);
	//S_Props prop = { E_值类型::e_Type_UI64, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_UI64, value, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_Props f_alloc_Vec2Prop(vec2* value, std::u16string name, vec2 初始值 = {}, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (vec2*)malloc(sizeof(vec2));
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_Vec2, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 2, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_Vec2, value, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_值映射类型 = 映射类型;
	return prop;
}
Inline S_Props f_alloc_iVec2Prop(ivec2* value, std::u16string name, ivec2 初始值 = {}, int32 min = 0xffffffff, int32 max = 0x0fffffff) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (ivec2*)malloc(sizeof(ivec2));
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_iVec2, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 2, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_iVec2, value, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_值映射类型 = 映射类型;
	return prop;
}
Inline S_Props f_alloc_uVec2Prop(uvec2* value, std::u16string name, uvec2 初始值 = {}, uint32 min = 0, uint32 max = 0xffffffff) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (uvec2*)malloc(sizeof(uvec2));
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_uVec2, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 2, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_uVec2, value, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}


inline S_Props f_alloc_Vec3Prop(vec3* value, std::u16string name, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (vec3*)malloc(sizeof(vec3));
		(*value) = {0,0,0};
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_Vec3, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 3, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_Vec3, value, name, 映射类型);
	//prop.m_值映射类型 = 值映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
inline S_Props f_alloc_RgbaProp(S_RGBA8UI* value, std::u16string name, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (S_RGBA8UI*)malloc(sizeof(S_RGBA8UI));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_RGBA8, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 4, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_RGBA8, value, name, 映射类型);
	//prop.m_值映射类型 = 值映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

inline S_Props f_alloc_StrProp(std::u16string* value, std::u16string name, fp_PropUpdate fn_update = nullptr) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = new std::u16string;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_Str, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_Str, value, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = fn_update;
	return prop;
}
Inline std::u16string& f_prop_Str(S_Props& prop) {
	return *((std::u16string*)prop.m_Value);
}
Inline std::u16string f_prop_Str(const S_Props& prop) {
	return *((std::u16string*)prop.m_Value);
}
Inline DEF_WString f_prop_WStr(const S_Props& prop) {
	return *((DEF_WString*)prop.m_Value);
}

inline S_Props f_alloc_LineStrProp(DEF_wString* value, const std::u16string& name, const DEF_WString& 初始值 = u"", fp_PropUpdate fn_update = nullptr) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = new DEF_wString;
		(*value) = (初始值);
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	//S_Props prop = { E_值类型::e_Type_LineText, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 1, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_LineText, value, name, 映射类型);
	//prop.m_值映射类型 = 映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = fn_update;
	return prop;
}
Inline std::u16string& f_prop_LineStr(S_Props& prop) {
	return *((std::u16string*)prop.m_Value);
}
Inline const std::u16string& f_prop_LineStr(const S_Props& prop) {
	return *((std::u16string*)prop.m_Value);
}


inline S_Props f_alloc_PathProp(std::filesystem::path* value, std::u16string name, const DEF_WString& 初始值 = u"") {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = new std::filesystem::path();
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_路径, value, name, 映射类型);
	//prop.m_值映射类型 = 映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}




Inline vec3& f_prop_Vec3(S_Props& prop) {
	return *((vec3*)prop.m_Value);
}
Inline vec3& f_prop_Vec3(const S_Props& prop) {
	return *((vec3*)prop.m_Value);
}
Inline ivec2& f_prop_iVec2(S_Props& prop) {
	return *((ivec2*)prop.m_Value);
}
Inline uvec2& f_prop_uVec2(S_Props& prop) {
	return *((uvec2*)prop.m_Value);
}
Inline S_RGBA8UI& f_prop_Rgba8UI(S_Props& prop) {
	return *((S_RGBA8UI*)prop.m_Value);
}

Inline std::filesystem::path& f_prop_Path(S_Props& prop) {
	return *((std::filesystem::path*)prop.m_Value);
}
Inline const std::filesystem::path& f_prop_Path(const S_Props& prop) {
	return *((std::filesystem::path*)prop.m_Value);
}


template<typename T>
inline void f_Prop_setValue(S_Props& prop, T value) {
	*((T*)prop.m_Value) = value;
	if(prop.m_UI->m_Update) prop.m_UI->m_Update(prop);
}









typedef enum : uint64 {

}E_Err;
